package com.have.blog.web.redis.impl;

import com.have.blog.config.service.RedisService;
import com.have.blog.model.models.BlogLike;
import com.have.blog.web.constant.RedisConstant;
import com.have.blog.web.redis.LikeRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class LikeRedisServiceImpl implements LikeRedisService {
    @Value("${redis.admin.database}")
    private String REDIS_KEY_DATABASE;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public Double getBlogLikeCount(Integer blogUid) {
        StringBuilder sb = new StringBuilder();
        String key = REDIS_KEY_DATABASE + RedisConstant.SEG
                + RedisConstant.BLOG_LIKE + RedisConstant.SEG
                + RedisConstant.COUNT_KEY;
        Double score = redisTemplate.opsForZSet().score(key, blogUid);
        return score;
    }

    @Override
    public void putBlogLikeCount(Integer blogUid, Double count) {
        String key = REDIS_KEY_DATABASE + RedisConstant.SEG
                + RedisConstant.BLOG_LIKE + RedisConstant.SEG
                + RedisConstant.COUNT_KEY;
        redisTemplate.opsForZSet().add(key, blogUid, count);
        redisTemplate.expire(key, 1, TimeUnit.DAYS);
    }

    @Override
    public List<BlogLike> getAllLikeFromRedis() {
        Integer threshold = 2000;
        String key =  REDIS_KEY_DATABASE + RedisConstant.SEG
                + RedisConstant.BLOG_LIKE;
        Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(key, ScanOptions.NONE);
        List<BlogLike> blogLikeList = new ArrayList<>();
        int cur = 0;
        while (cursor.hasNext() && cur++ < threshold) {
            Map.Entry<Object, Object> entry = cursor.next();
            String hKey = (String) entry.getKey();
            Integer value = (Integer) entry.getValue();
            String[] split = hKey.split(RedisConstant.SEG);
            String blogUid = split[0];
            String userUid = split[1];
            BlogLike blogLike = new BlogLike();
            blogLike.setUserUid(Integer.valueOf(userUid));
            blogLike.setBlogUid(Integer.valueOf(blogUid));
            blogLike.setStatus(value);
            blogLikeList.add(blogLike);
            redisTemplate.opsForHash().delete(key, hKey);
        }
        return blogLikeList;
    }
}
